package com.conan.app.dailyflickr.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import android.content.ContentValues;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;

public class BitmapUtils {

	private static final int UNCONSTRAINED = -1;
	private static final boolean ENABLE_LOG = true;
	private static final String TAG = "BitmapUtils";

	
	public void saveToSDCard(Context context, Bitmap bitmap, String name, String nam) {
	    boolean mExternalStorageAvailable = false;
	    boolean mExternalStorageWriteable = false;
	    String state = Environment.getExternalStorageState();
	    if (Environment.MEDIA_MOUNTED.equals(state)) {
	        mExternalStorageAvailable = mExternalStorageWriteable = true;
	        Log.v(TAG, "SD Card is available for read and write "
	                + mExternalStorageAvailable + mExternalStorageWriteable);
	        saveFile(context, bitmap, name, nam);
	    } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
	        mExternalStorageAvailable = true;
	        mExternalStorageWriteable = false;
	        Log.v(TAG, "SD Card is available for read "
	                + mExternalStorageAvailable);
	    } else {
	        mExternalStorageAvailable = mExternalStorageWriteable = false;
	        Log.v(TAG, "Please insert a SD Card to save your Video "
	                + mExternalStorageAvailable + mExternalStorageWriteable);
	    }
	}

	private void saveFile(Context context, Bitmap bitmap, String fullname, String nam) {

	    ContentValues values = new ContentValues();

	    File outputFile = new File(fullname);
	    values.put(MediaStore.MediaColumns.DATA, outputFile.toString());
	    values.put(MediaStore.MediaColumns.TITLE, nam);
	    values.put(MediaStore.MediaColumns.DATE_ADDED, System
	            .currentTimeMillis());
	    values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg");
	    Uri uri = context.getContentResolver().insert(
	            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,

	            values);;

	    try {
	        OutputStream outStream = context.getContentResolver()
	                .openOutputStream(uri);
	        bitmap.compress(Bitmap.CompressFormat.JPEG, 95, outStream);

	        outStream.flush();
	        outStream.close();
	    } catch (FileNotFoundException e) {
	        e.printStackTrace();
	    } catch (IOException e) {
	        e.printStackTrace();
	    }
	    bitmap.recycle();
	}
	
	public static Bitmap compressToMiniThumbnail(Bitmap source,
			boolean needRecycleSource) {
		return compressToMiniThumbnail(source, needRecycleSource, 96);
	}

	public static Bitmap compressToMiniThumbnail(Bitmap source,
			boolean needRecycleSource, int size) {
		if (source == null)
			return null;

		// Log.d(TAG, "w=" + source.getWidth() + "  h=" + source.getHeight());

		int MINI_THUMB_TARGET_SIZE = size;

		if (source.getWidth() < size || source.getHeight() < size)
			return source;

		float scale;
		if (source.getWidth() < source.getHeight()) {
			scale = MINI_THUMB_TARGET_SIZE / source.getWidth();
		} else {
			scale = MINI_THUMB_TARGET_SIZE / source.getHeight();
		}
		Matrix matrix = new Matrix();
		matrix.setScale(scale, scale);
		Bitmap miniThumbnail = transform(matrix, source,
				MINI_THUMB_TARGET_SIZE, MINI_THUMB_TARGET_SIZE, false);
		if (needRecycleSource) {
			source.recycle();
		}

		return miniThumbnail;
	}

	public static synchronized Bitmap transform(Matrix scaler, Bitmap source,
			int targetWidth, int targetHeight, boolean scaleUp) {
		return transform(scaler, source, targetWidth, targetHeight, scaleUp,
				Bitmap.Config.RGB_565);
	}

	public static synchronized Bitmap transform(Matrix scaler, Bitmap source,
			int targetWidth, int targetHeight, boolean scaleUp,
			Bitmap.Config config) {
		if (config == null) {
			config = Bitmap.Config.RGB_565;
		}
		// Log.d(TAG, "source " + source.getWidth() + " " + source.getHeight());
		int deltaX = source.getWidth() - targetWidth;
		int deltaY = source.getHeight() - targetHeight;
		// Log.d(TAG, "deltaX " + deltaX + " deltaY " + deltaY);
		if ((!scaleUp) && ((deltaX < 0) || (deltaY < 0))) {
			Bitmap b2 = null;
			try {
				b2 = Bitmap.createBitmap(targetWidth, targetHeight, config);
			} catch (OutOfMemoryError oome) {
				Log.e(TAG, "memory is not enough to alloc bitmap", oome);
				return null;
			}
			Canvas c = new Canvas(b2);

			int deltaXHalf = Math.max(0, deltaX / 2);
			int deltaYHalf = Math.max(0, deltaY / 2);
			Rect src = new Rect(deltaXHalf, deltaYHalf, deltaXHalf
					+ Math.min(targetWidth, source.getWidth()), deltaYHalf
					+ Math.min(targetHeight, source.getHeight()));

			Rect dst = new Rect(0, 0, targetWidth, targetHeight);
			c.drawBitmap(source, src, dst, null);
			return b2;
		}
		float bitmapWidthF = source.getWidth();
		float bitmapHeightF = source.getHeight();

		float bitmapAspect = bitmapWidthF / bitmapHeightF;
		float viewAspect = targetWidth / targetHeight;

		if (bitmapAspect > viewAspect) {
			float scale = targetHeight / bitmapHeightF;
			if ((scale < 0.9F) || (scale > 1.0F))
				scaler.setScale(scale, scale);
			else
				scaler = null;
		} else {
			float scale = targetWidth / bitmapWidthF;
			if ((scale < 0.9F) || (scale > 1.0F))
				scaler.setScale(scale, scale);
			else
				scaler = null;
		}
		Bitmap b1;
		if (scaler != null) {
			try {
				b1 = Bitmap.createBitmap(source, 0, 0, source.getWidth(),
						source.getHeight(), scaler, true);
			} catch (OutOfMemoryError oome) {
				Log.e(TAG, "out of memory when create scaler one", oome);
				return null;
			}
		} else
			b1 = source;

		Log.d(TAG, "b1 " + b1.getWidth() + " " + b1.getHeight());
		int dx1 = Math.max(0, b1.getWidth() - targetWidth);
		int dy1 = Math.max(0, b1.getHeight() - targetHeight);

		Bitmap b2 = null;
		try {
			b2 = Bitmap.createBitmap(b1, dx1 / 2, dy1 / 2, targetWidth,
					targetHeight);
		} catch (OutOfMemoryError oome) {
			Log.e(TAG, "final tune image in transform cause oome", oome);
		}

		if (b1 != source) {
			b1.recycle();
		}
		return b2;
	}
}
